package com.kuafuai.api.service;

import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.kuafuai.common.domin.ErrorCode;
import com.kuafuai.common.exception.BusinessException;
import com.kuafuai.system.entity.ApiMarket;
import com.kuafuai.system.service.ApiMarketService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Type;
import java.util.Map;

@Service
@Slf4j
public class ApiSdkGeneratorService {

    @Autowired
    private ApiMarketService apiMarketService;

    private final Gson gson = new Gson();
    private final Type varRowType = new TypeToken<Map<String, Map<String, String>>>() {
    }.getType();

    // HTTP方法映射
    private static final String[] METHOD_MAP = {"GET", "POST", "PUT", "DELETE", "PATCH"};

    /**
     * 根据API Market ID生成JS SDK代码
     *
     * @param marketId API市场ID
     * @return JS SDK代码
     */
    public String generateSdkByMarketId(Integer marketId) {
        ApiMarket apiMarket = apiMarketService.getById(marketId);
        if (apiMarket == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "API不存在");
        }
        return generateSdk(apiMarket);
    }

    /**
     * 生成JS SDK代码
     *
     * @param apiMarket API市场数据
     * @return JS SDK代码
     */
    public String generateSdk(ApiMarket apiMarket) {
        String name = apiMarket.getName();
        if (StringUtils.isEmpty(name)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "API名称不能为空");
        }

        // 生成类名: 首字母大写 + Builder
        String className = capitalize(name) + "Builder";
        String moduleName = name + "Module";

        // 获取HTTP方法
        String httpMethod = getHttpMethod(apiMarket.getMethod());

        // 生成API URL
        String apiUrl = "/api/" + name;

        // 解析参数
        Map<String, Map<String, String>> params = parseVarRow(apiMarket.getVarRow());

        // 生成代码
        StringBuilder code = new StringBuilder();

        // 生成类定义
        code.append(generateClassDefinition(className, name, apiUrl));
        code.append("\n");

        // 生成构造函数
        code.append(generateConstructor(className));
        code.append("\n");

        // 生成参数方法
        code.append(generateParameterMethods(params));
        code.append("\n");

        // 生成执行方法
        code.append(generateExecuteMethod(className, name, httpMethod));
        code.append("\n");

        // 生成then方法
        code.append(generateThenMethod());
        code.append("}\n\n");

        // 生成导出函数
        code.append(generateExportFunction(moduleName, className));

        return code.toString();
    }

    /**
     * 解析varRow JSON
     */
    private Map<String, Map<String, String>> parseVarRow(String varRow) {
        if (StringUtils.isEmpty(varRow)) {
            return Maps.newHashMap();
        }
        try {
            return gson.fromJson(varRow, varRowType);
        } catch (Exception e) {
            log.error("解析varRow失败: {}", e.getMessage());
            return Maps.newHashMap();
        }
    }

    /**
     * 获取HTTP方法名
     */
    private String getHttpMethod(Integer method) {
        if (method == null || method < 0 || method >= METHOD_MAP.length) {
            return "POST";
        }
        return METHOD_MAP[method];
    }

    /**
     * 首字母大写
     */
    private String capitalize(String str) {
        if (StringUtils.isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    /**
     * 生成类定义
     */
    private String generateClassDefinition(String className, String apiName, String apiUrl) {
        return String.format("class %s {\n    static API_MAP = {\n        %s: \"%s\"\n    };",
                className, apiName, apiUrl);
    }

    /**
     * 生成构造函数
     */
    private String generateConstructor(String className) {
        return "    constructor(client) {\n" +
                "        this.client = client;\n" +
                "        this.params = {};\n" +
                "    }";
    }

    /**
     * 生成参数方法
     */
    private String generateParameterMethods(Map<String, Map<String, String>> params) {
        if (params.isEmpty()) {
            return "";
        }

        StringBuilder methods = new StringBuilder();
        for (String paramName : params.keySet()) {
            Map<String, String> paramInfo = params.get(paramName);
            String desc = paramInfo.getOrDefault("desc", "");

            methods.append("    /**\n");
            methods.append("     * ").append(desc).append("\n");
            methods.append("     */\n");
            methods.append("    ").append(paramName).append("(value) {\n");
            methods.append("        this.params.").append(paramName).append(" = value;\n");
            methods.append("        return this;\n");
            methods.append("    }\n\n");
        }
        return methods.toString();
    }

    /**
     * 生成执行方法
     */
    private String generateExecuteMethod(String className, String apiName, String httpMethod) {
        StringBuilder method = new StringBuilder();
        method.append("    async _execute() {\n");
        method.append("        const url = ").append(className).append(".API_MAP.").append(apiName).append(";\n");

        if ("GET".equals(httpMethod)) {
            // GET请求使用query参数
            method.append("        const queryString = new URLSearchParams(this.params).toString();\n");
            method.append("        const fullUrl = queryString ? `${url}?${queryString}` : url;\n");
            method.append("        return await this.client.request(fullUrl, {\n");
            method.append("            method: \"").append(httpMethod).append("\"\n");
            method.append("        });\n");
        } else {
            // POST/PUT/DELETE/PATCH使用body
            method.append("        return await this.client.request(url, {\n");
            method.append("            method: \"").append(httpMethod).append("\",\n");
            method.append("            body: JSON.stringify(this.params)\n");
            method.append("        });\n");
        }

        method.append("    }");
        return method.toString();
    }

    /**
     * 生成then方法
     */
    private String generateThenMethod() {
        return "\n    then(resolve, reject) {\n" +
                "        this._execute().then(resolve, reject);\n" +
                "    }\n";
    }

    /**
     * 生成导出函数
     */
    private String generateExportFunction(String moduleName, String className) {
        return String.format("export function %s(client) {\n    return new %s(client);\n}",
                moduleName, className);
    }
}
